﻿#define NOMINMAX
#include <chrono>
#include <cstdlib>
#include <fstream>
#include <iostream>
#include <thread>

#include "../src/util/time_util.hh"
#include "box/service_box.hh"
#include "box/service_context.hh"
#include "client.h"
#include "detail/lang_impl.hh"
#include "guildservicewelfare.service.GuildClientWelfare.impl.h"
#include "guild.h"

void setup()
{
  {
    std::ofstream ofs;
    ofs.open("config_service_box.cfg", std::ios::trunc | std::ios::out);
    ofs << "listener = {\r"
           "   host = (\"127.0.0.1:10002\")\r"
           "}\r"
           "box_channel_recv_buffer_len = 1024\r"
           "box_name = \"guild_client\"\r"

           "service = {\r"
           "   service_dir = "
#ifdef _WIN32
           "\"../../../../../../../publish/bin/service/Debug\"\r"
#else
           "\"../../../../../../../../publish/bin/service\"\r"
#endif // _WIN32
           "}\r"

           "debugger = {\r"
           "   enable = \"true\"\r"
           "   listen = \"0.0.0.0:10888\"\r"
           "}\r"

           "statistics = {\r"
           "   is_open_rpc_stat = \"true\"\r"
           "}";

    ofs.close();
  }
}

void client_op(Client &client)
{
  uint64_t token = rand() % 100 + 1000;
  uint64_t member_token = token;
  uint64_t guild_id = 0;
  std::string name = "xxx";
  bool is_auto_approval = false;
  uint32_t icon_id = 0;
  std::string declaration = "";
  std::string announce = "";

  client.Register(guild_service::kTestAccountList[0],
                  guild_service::kTestPasswdList[0]);

  client.CreateGuild();

  client.GetGuildBrief();

  client.GetGuildMember(member_token);

  client.GetGuildBriefList(token, 10);

  client.SearchGuild(name);

  client.GetGuildApplication(token);

  client.ApplyJoinGuild(token, guild_id);

  client.KickOutGuildMember(token, member_token);

  client.SetAutoApproval(token, is_auto_approval);

  client.ChangeGuildIconId(token, icon_id);

  client.ChangeGuildName(name);

  client.ChangeGuildDeclaration(declaration);

  client.ChangeGuildAnnounce(announce);

  client.LoginWelfare();

  client.SendGuildRedEnvelope();

  client.LogoutWelfare();

  client.BuildingUpgrade();

  client.QuitGuild(token);

  client.Unregister();
}

void run(time_t time)
{
  const char *argv_client[] = {"guild_client",
                               "--config=config_service_box.cfg", "--proxy-host=127.0.0.1:9888"};

  kratos::service::ServiceBox service_box;
  if (!service_box.start(3, argv_client))
  {
    return;
  }

  auto start = kratos::util::get_os_time_millionsecond();
  while (true)
  {
    if (service_box.is_wait_stop())
    {
      break;
    }

    service_box.update();
    auto now = kratos::util::get_os_time_millionsecond();
    if (now - start > 2000)
    {
      break;
    }

    std::this_thread::sleep_for(std::chrono::milliseconds(10));
  }

  start = kratos::util::get_os_time_millionsecond();

  Client client(service_box);
  int cnt = 0;
  co(
      // TODO command queue
      for (int i = cnt; i < 1; ++i) { client_op(client); } cnt++;)

      while (true) {
    if (service_box.is_wait_stop()) {
      break;
    }
    service_box.update();

    auto now = kratos::util::get_os_time_millionsecond();
    if (now - start > time) {
      break;
    }

    std::this_thread::sleep_for(std::chrono::milliseconds(10));
  }

  std::cout << "service box stop" << '\n';

  service_box.stop();
}

int main(int argc, char *argv[])
{
  setup();

  time_t time = 5000;
  if (argc > 1)
  {
    time = std::stoll(argv[1]);
  }

  run(time);

  return 0;
}
